﻿//  Copyright (c) 2011 Ray Liang (http://www.dotnetage.com)
//  Dual licensed under the MIT and GPL licenses:
//  http://www.opensource.org/licenses/mit-license.php
//  http://www.gnu.org/licenses/gpl.html

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.UI;
using System.Collections;

namespace DNA.Mvc.jQuery
{
    //public abstract class jQueryNavigableViewBindingBuilder<TOptions, TComponent, TBuilder> : jQueryComponentBuilder<TOptions, TComponent, TBuilder>
    //    where TComponent : DataBindableComponentContainer<NavigableView>
    //    where TBuilder : ViewComponentBuilder<TComponent, TBuilder>
    //{
    //    //protected Action clientTemplate;
    //    //protected Func<object,object> clientInlineTemplate;
    //    protected IHtmlTemplate _template=new HtmlTemplate();
    //    protected string remoteUrl;
    //    protected string httpMethod;

    //    public jQueryNavigableViewBindingBuilder(TComponent component, AjaxHelper helper) : base(component, helper) { }

    //    public TBuilder ClientBind(string url, Action template)
    //    {
    //        return this.ClientBind(url, "POST", template);
    //    }

    //    public TBuilder ClientBind(string url, string method, Action template)
    //    {
    //        //clientTemplate = template;
    //        _template.Content = template;
    //        remoteUrl = url;
    //        httpMethod = method;
    //        return this as TBuilder;
    //    }

    //    public TBuilder ClientBind(string url, Func<object, object> template)
    //    {
    //        return this.ClientBind(url,"POST", template);
    //    }

    //    public TBuilder ClientBind(string url, string method, Func<object, object> template)
    //    {
    //        _template.InlineContent = template;
    //        remoteUrl = url;
    //        httpMethod = method;
    //        return this as TBuilder;
    //    }

    //    protected void RenderClientTemplate(HtmlTextWriter writer)
    //    {
    //        writer.WriteBeginTag("script");
    //        writer.WriteAttribute("id", Component.Id + "_tmpl");
    //        writer.WriteAttribute("type", "text/x-jquery-tmpl");
    //        writer.Write(HtmlTextWriter.TagRightChar);
    //        _template.WriteTo(writer);
    //        writer.WriteEndTag("script");
    //    }

    //    public TBuilder Items(Action<NavigableViewFactory> value)
    //    {
    //        var factory = new NavigableViewFactory(Component, Helper);
    //        value.Invoke(factory);
    //        return this as TBuilder;
    //    }

    //    public TBuilder ItemDataBound(Action<NavigableView> value)
    //    {
    //        return this.ItemDataBound(null, value);
    //    }

    //    public TBuilder ItemDataBound(Action<IDictionary<string,object>> attributes, Action<NavigableView> value)
    //    {
    //        Component.ItemDataBoundAttributes = attributes;
    //        Component.ItemDataBoundTemplate = value;
    //        return this as TBuilder;
    //    }

    //    public TBuilder Bind(Enum _enum)
    //    {
    //        string[] names = Enum.GetNames(_enum.GetType());
    //        var _list = new List<NavigatableNode>();

    //        for (int i = 0; i < names.Length; i++)
    //        {
    //            _list.Add(new NavigatableNode()
    //            {
    //                Text = names[i],
    //                Value = names[i]
    //            });
    //        }
    //        // Options(opts => { opts.SelectedValue = _enum.ToString(); });
    //        return Bind<NavigatableNode>(_list, "Text", "Value");
    //    }

    //    public TBuilder Bind(string[] values)
    //    {
    //        var _list = new List<NavigatableNode>();
    //        for (int i = 0; i < values.Length; i++)
    //        {
    //            _list.Add(new NavigatableNode()
    //            {
    //                Text = values[i],
    //                Value = values[i]
    //            });
    //        }
    //        return Bind<NavigatableNode>(_list, "Text", "Value");
    //    }

    //    public TBuilder Bind<T>(IEnumerable<T> collection, string dataTextField, string dataValueField)
    //    {
    //        foreach (var item in collection)
    //        {
    //            var navItem = new NavigableView()
    //            {
    //                Title = DataBinder.Eval(item, dataTextField) as string,
    //                Value = DataBinder.Eval(item, dataValueField) as string
    //            };
    //            ((IComponentItemContainer<NavigableView>)Component).Items.Add(navItem);
    //            ((IComponentItemContainer<NavigableView>)Component).OnItemAdded(navItem);
    //        }
    //        return this as TBuilder;
    //    }

    //    public TBuilder Bind<T>(IEnumerable<T> collection)
    //        where T : INavigtable
    //    {
    //        return this.Bind(collection, null);
    //    }

    //    public TBuilder Bind<T>(IEnumerable<T> collection, MapAction<T, NavigableView> mapper)
    //        where T : INavigtable
    //    {
    //        foreach (var item in collection)
    //        {
    //            var navItem = new NavigableView(item);
    //            if (mapper != null)
    //            {
    //                if (mapper.Invoke(item, navItem) == false)
    //                    continue;
    //            }
    //            ((IComponentItemContainer<NavigableView>)Component).Items.Add(navItem);
    //            ((IComponentItemContainer<NavigableView>)Component).OnItemAdded(navItem);
    //        }
    //        return this as TBuilder;
    //    }

    //    protected virtual void RenderItemHolderAttributes(HtmlTextWriter writer) { }

    //    protected virtual object OnRenderItemAttributes(NavigableView item) { return null; }
        
    //    private void RenderAttributes(HtmlTextWriter writer, object htmlAttributes)
    //    {
    //        if (htmlAttributes != null)
    //        {
    //            var attrs = ObjectHelper.ConvertObjectToDictionary(htmlAttributes);
    //            foreach (var key in attrs.Keys)
    //            {
    //                var val = attrs[key] == null ? "" : attrs[key].ToString();
    //                writer.WriteAttribute(key, val);
    //            }
    //        }
    //    }

    //    public override void Render()
    //    {
    //        using (var writer = new HtmlTextWriter(Helper.ViewContext.Writer))
    //        {
    //            Component.RenderBeginTag(writer);
    //            Component.RenderContent(writer);

    //            writer.WriteBeginTag("ul");
    //            RenderItemHolderAttributes(writer);
    //            writer.Write(HtmlTextWriter.TagRightChar);

    //            if (clientTemplate == null)
    //            {
    //                foreach (var item in ((IComponentItemContainer<NavigableView>)Component).Items)
    //                {
    //                    var itemAttrs = OnRenderItemAttributes(item);

    //                    if (item.Template != null)
    //                    {
    //                        if (itemAttrs == null)
    //                            writer.WriteFullBeginTag("li");
    //                        else
    //                        {
    //                            writer.WriteBeginTag("li");
    //                            RenderAttributes(writer, itemAttrs);
    //                            writer.Write(Html32TextWriter.TagRightChar);
    //                        }
    //                        writer.WriteBeginTag("input");
    //                        writer.WriteAttribute("type", "hidden");
    //                        writer.WriteAttribute("value", item.Value != null ? item.Value.ToString() : "");
    //                        writer.Write(HtmlTextWriter.SelfClosingTagEnd);
    //                        item.Template();
    //                        writer.WriteEndTag("li");
    //                        continue;
    //                    }

    //                    if (Component.ItemDataBoundTemplate != null)
    //                    {
    //                        if (Component.ItemDataBoundAttributes != null)
    //                        {
    //                            if (itemAttrs == null)
    //                                itemAttrs = new Dictionary<string, object>();
    //                            Component.ItemDataBoundAttributes.Invoke((Dictionary<string, object>)itemAttrs);
    //                        }

    //                        if (itemAttrs == null)
    //                            writer.WriteFullBeginTag("li");
    //                        else
    //                        {
    //                            writer.WriteBeginTag("li");
    //                            RenderAttributes(writer, itemAttrs);
    //                            writer.Write(Html32TextWriter.TagRightChar);
    //                        }
    //                        writer.WriteBeginTag("input");
    //                        writer.WriteAttribute("type", "hidden");
    //                        writer.WriteAttribute("value", item.Value != null ? item.Value.ToString() : "");
    //                        writer.Write(HtmlTextWriter.SelfClosingTagEnd);
    //                        Component.ItemDataBoundTemplate.Invoke(item);
    //                        writer.WriteEndTag("li");
    //                        continue;
    //                    }

    //                    var builder = new NodeUIBuilder();
    //                    if (itemAttrs == null)
    //                        builder.WriteNode(item);
    //                    else
    //                        builder.WriteNode(item, itemAttrs);
    //                    writer.Write(builder.ToString());
    //                }
    //            }

    //            writer.WriteEndTag("ul");
    //            Component.RenderEndTag(writer);

    //            if (clientTemplate != null)
    //                RenderClientTemplate(writer);
    //        }

    //        Helper.jQuery(Component.Id, jQueryPluginName, options);
    //    }
    //}

    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="TModel"></typeparam>
    /// <typeparam name="TItem"></typeparam>
    /// <typeparam name="TOptions"></typeparam>
    /// <typeparam name="TContainer"></typeparam>
    /// <typeparam name="TBuilder"></typeparam>
    public abstract class jQueryDataListComponentBuilder<TModel, TContainer,TItem, TOptions, TBuilder> : jQueryComponentBuilder<TOptions, TContainer, TBuilder>
        where TModel :class
        where TItem : ViewComponent
        where TContainer : DataBindableContainer<TModel,TItem>
        where TBuilder : jQueryDataListComponentBuilder<TModel, TContainer, TItem, TOptions, TBuilder>
    {
        public jQueryDataListComponentBuilder(TContainer containerComponent, ViewContext viewContext, IViewDataContainer viewContainer) : 
            base(containerComponent, viewContext, viewContainer) { }
        
        /// <summary>
        /// Binding model to component
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public TBuilder Bind(IEnumerable<TModel> model) 
        {
            Component.Model = model;
            return this as TBuilder;
        }

        /// <summary>
        /// Specified the bind model template for Razor.
        /// </summary>
        /// <param name="template"></param>
        /// <returns></returns>
        public TBuilder ItemTemplate(Func<TModel, object> template)
        {
            Component.ItemTemplate.InlineContent = template;
            return this as TBuilder;
        }

        /// <summary>
        /// Specified the bind model template for ASPX
        /// </summary>
        /// <param name="template"></param>
        /// <returns></returns>
        public TBuilder ItemTemplate(Action<TModel> template)
        {
            Component.ItemTemplate.Content = template;
            return this as TBuilder;
        }
    }

}
